using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Godot;

public partial class BaseLevelManager : Node2D
{
    public void SetCurrentCommand(RobotUICommand cmd)
    {
        CurrentCommand = cmd;
    }
    void LoadLevelConfig()
    {
        var json = FileUtil.ReadString(Path.LEVEL_ROOT + configName + ".json");
        levelModel = JSONUtil.Parse<LevelModel>(json);
    }

    void GetChildComponents()
    {

        MapManager = GetNode<BaseMapManager>("MapManager");
        RobotManager = GetNode<RobotManager>("RobotManager");
        RobotManager.OnRobotMoveEnd += OnRobotMoveEndHandler;
        RobotManager.OnEnemyRoundEnd += OnEnemyRoundEndHandler;
        RobotManager.OnRobotDestroy += OnRobotDestroyHandler;

        Cursor = GetNode<Cursor>("Cursor");
        Cursor.Init(this, MapManager);
        Cursor.OnPressed += OnCursorPressedHandler;
        BattleManager = GetNode<BattleManager>("BattleManager");
        BattleManager.Init(this, MapManager);
        BattleManager.BattleEnd += OnBattleEndHandler;
        BattleManager.BattleStart += OnStartBattleHandler;
        VFXManager = GetNode<VFXManager>("VFXManager");
        VFXManager.OnVFXEnd += OnVFXEndHandler;

        stateMachime = GetNode<LevelStateMachime>("LevelStateMachime");

        UIRoot = GetNode<Node>("UIRoot");
        UIRobotInfo = UIRoot.GetNode<RobotInfo>("RobotInfo");
        UIRobotInfo.OnRobotCommand += OnRobotCommandHandler;
        UIRobotDetail = UIRoot.GetNode<RobotDetailInfo>("RobotDetailInfo");
        UILevelInfo = UIRoot.GetNode<LevelInfo>("LevelInfo");
        UILevelInfo.Init(this);
        UILevelInfo.OnMenuButtonCommand += OnMenuButtonCommandHandler;
        UILevelInfo.OnRobotListItemPressed += OnRobotListItemPressedHandler;
        UIRobotWeaponSelection = UIRoot.GetNode<RobotWeaponSelection>("RobotWeaponSelection");
        UIRobotWeaponSelection.OnSelectWeapon += OnSelectWeaponHandler;
        UIConfirm = UIRoot.GetNode<UIConfirm>("UIConfirm");

        UISkillSelection = UIRoot.GetNode<PilotSkillSelection>("PilotSkillSelection");
        UISkillSelection.OnSkillItemSelect += OnSkillItemSelectHandler;
    }

    void InitCallable()
    {
        endTargetRobotActionCallable = Callable.From(EndTargetRobotAction);
        endRoundCallable = Callable.From(EndRoundHandler);
    }

    public override void _Ready()
    {
        GameManager.Instance.LevelManager = this;
        LoadLevelConfig();
        GetChildComponents();
        InitCallable();
        RobotManager.CreateLevelRobots(levelModel);
        CurrentRobot = RobotManager.GetRobotByTemplateId(levelModel.PrimaryRobot);
        StartLevel();
    }

    public void StartLevel()
    {
        NextRound();
    }

    public Robot GetRobotOnPos(Vector2 pos)
    {
        return RobotManager.AllRobotList.Find(v => MapManager.LocalToMap(v.Position) == MapManager.LocalToMap(pos) && v.Visible);
    }

    public Robot GetCursorOnRobot()
    {
        return GetRobotOnPos(Cursor.CurSorPosition);
    }

    public void NextRound()
    {
        CheckLevelSuccessOrFail();
        RobotManager.RoundStartActions();
        UIRobotInfo.Reset();
        CurrentRoundIndex++;
        RefreshUI();
        // 判断当前回合有没有剧情
        var cfg = levelModel.RoundEvents.Find(v => v.Round == CurrentRoundIndex);
        if (cfg?.Events?.Count > 0)
        {
            roundEvents = cfg.Events;
        }
        else
        {
            roundEvents = null;
        }
        stateName = GetStateName();
        stateMachime.RunState(stateName);
    }

    public string GetStateName()
    {
        // 如果有剧情
        if (roundEvents?.Count > 0)
        {
            currentEventIndex++;
            if (currentEventIndex < roundEvents.Count)
            {
                var cfg = roundEvents[currentEventIndex];
                CurrentEvent = cfg;
                return StoryType2StateName(cfg.EventType);
            }
            else
            {
                currentEventIndex = -1;
            }
        }
        // 剧情已经播放完 ， 如果是第0回合
        if (CurrentRoundIndex == 0)
        {
            return "LevelStartScreenState";
        }
        if (levelSunncess)
        {
            return "LevelSuccessState";
        }
        if (levelFail)
        {
            return "LevelFailState";
        }
        // 没有剧情， 则是玩家操作状态
        return "PlayerInputState";
    }

    private string StoryType2StateName(RoundEventType eventType)
    {
        return eventType switch
        {
            RoundEventType.Talks => CurrentRoundIndex == 0 ? "TalkBeforeLevelState" : "LevelRoundTalkState",
            RoundEventType.AddEnemyRobot => "AddEnemyRobotState",
            RoundEventType.AddPlayerRobot => "AddPlayerRobotState",
            RoundEventType.AddAllyRobot => "AddAllyRobotState",
            // case RoundEventType.ChangeRobotBehavior:
            //     return "AddRobotState";
            _ => "PlayerInputState",
        };

    }

    public async Task FocusCurrentRobot()
    {
        Cursor.FocusTarget(CurrentRobot);
        await ToSignal(Cursor, nameof(Cursor.CameraMoveEnd));
        UIRobotInfo.AnimateShow(CurrentRobot);
    }

    public bool IsListsEmpty<T>(List<List<T>> val)
    {
        return !val.Any(v => v.Count > 0);
    }

    bool levelSunncess = false;
    bool levelFail = false;

    public void CheckLevelSuccessOrFail()
    {
        var success = levelModel.Success.Condiction;
        var fail = levelModel.Fail.Condiction;
        // 胜利条件
        levelSunncess = success switch
        {
            LevelCondiction.KillAllEnemy => CheckKillAllEnemy(),
            LevelCondiction.KillTargetEnemy => CheckKillTargetEnemy(),
            _ => false,

        };
        if (levelSunncess)
        {
            RunLevelSuccess();
            return;
        }
        levelFail = fail switch
        {
            LevelCondiction.KillAllPlayer => CheckAllPlayerDead(),
            LevelCondiction.KillTargetPlayer => CheckProtectTargetDead(),
            LevelCondiction.KillTargetAlly => CheckTarAllyDeath(),
            _ => false,
        };

        if (levelFail)
        {
            RunLevelFial();
        }
    }

    private void RunLevelSuccess()
    {
        // 胜利剧情
        if (levelModel.Success.TriggerEvents.Count > 0)
        {
            roundEvents = levelModel.Success.TriggerEvents;
        }
        stateName = GetStateName();
        stateMachime.RunState(stateName);
    }


    private void RunLevelFial()
    {

    }


    private bool CheckTarAllyDeath()
    {
        var rid = levelModel.Success.CustomData["TargetRobot"].As<int>();
        var pid = levelModel.Success.CustomData["Pilot"].As<int>();
        var tar = RobotManager.AllyRobots.Find(v => v.Entity.TemplateID == rid && v.Entity.Pilot.TemplateID == pid);
        return tar == null || tar.IsDeath;
    }


    private bool CheckProtectTargetDead()
    {
        var rid = levelModel.Success.CustomData["TargetRobot"].As<int>();
        var pid = levelModel.Success.CustomData["Pilot"].As<int>();
        var tar = RobotManager.PlayerRobots.Find(v => v.Entity.TemplateID == rid && v.Entity.Pilot.TemplateID == pid);
        return tar == null || tar.IsDeath;
    }


    private bool CheckAllPlayerDead()
    {
        return RobotManager.PlayerRobots.All(v => v.IsDeath);
    }


    private bool CheckKillTargetEnemy()
    {
        var rid = levelModel.Success.CustomData["TargetRobot"].As<int>();
        var pid = levelModel.Success.CustomData["Pilot"].As<int>();
        var tar = RobotManager.EnemyRobots.Find(v => v.Entity.TemplateID == rid && v.Entity.Pilot.TemplateID == pid);
        return tar == null || tar.IsDeath;
    }


    private bool CheckKillAllEnemy()
    {
        return RobotManager.EnemyRobots.All(v => v.IsDeath);
    }

}
